package cn.com.bo.util;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

public class HiveService {
	static Logger logger = Logger.getLogger(HiveService.class);
	// hive的jdbc驱动类
	public static String dirverName;
	// 连接hive的URL hive1.2.1版本需要的是jdbc:hive2，而不是 jdbc:hive
	public static String url;
	// 登录linux的用户名 一般会给权限大一点的用户，否则无法进行事务形操作
	public static String user;
	// 登录linux的密码
	public static String pass;
	
	public static final char UNDERLINE = '_';  

	public HiveService(){
		dirverName = PropUtils.get("driverName");
		url = PropUtils.get("conn.url");
		user = PropUtils.get("conn.user");
		pass = PropUtils.get("conn.passowrd");
	}
	
	/**
	 * 创建连接
	 * 
	 * @return
	 * @throws SQLException
	 */
	public Connection getConn() {
		Connection conn = null;
		try {
			Class.forName(dirverName);
			conn = DriverManager.getConnection(url, user, pass);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return conn;
	}

    /** 
     * 按条件查找 
     * @since  2016年10月20日  
     * @param clazz 
     * @param sql 
     * @return 
     * @throws Exception 
     */  
    public <T> List<T> find(Class<T> clazz, String sql) {  
        if (sql == null || sql.length() == 0) {  
            logger.warn("查询sql语句不能为空");  
            return new ArrayList<T>();  
        }  
        logger.info("sql = {"+sql+"}");
        Connection connection = null;  
        Statement stmt = null;  
        ResultSet rs = null;  
  
        try {  
            connection = getConn();  
            stmt = connection.createStatement();    
            rs = stmt.executeQuery(sql);  
            return (List<T>) handler(clazz, rs);  
        } catch (Exception e) {  
            logger.error("sql = {"+sql+"}执行出错,Exception = {"+e.getLocalizedMessage()+"}");  
        } finally {  
            release(connection,stmt,rs);  
        }  
        return null;
    }  
      
    /** 
     * 释放资源 
     *  
     * @since 2016年8月31日 
     * @param conn 
     * @param st 
     * @param rs 
     */  
    private void release(Connection conn, Statement st, ResultSet rs) {  
        if (rs != null) {  
            try {  
                rs.close();  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
            rs = null;  
        }  
        if (st != null) {  
            try {  
                st.close();  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
            st = null;  
        }  
        if (conn != null) {  
            try {  
                conn.close();  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }  
    }  
    
    /** 
     * 组装list对象 
     * @author linbingwen 
     * @since  2016年10月20日  
     * @param clazz 
     * @param rs 
     * @return 
     * @throws Exception 
     */  
    private Object handler(Class clazz, ResultSet rs) throws Exception {  
        List list = new ArrayList();  
        try {  
            while (rs.next()) {  
                Object bean = clazz.newInstance();  
                
                ResultSetMetaData meta = rs.getMetaData();  
                int count = meta.getColumnCount();  
                for (int i = 0; i < count; i++) {  
                    String columnName = meta.getColumnName(i + 1);  
                    String name = columnName;  
                    if (columnName.contains(".")) {  
                        String[] split = columnName.split("\\.");  
                        if (split.length != 2) {  
                            throw  new Exception("输入的表名不正确！");  
                        }  
                        name =split[1];  
                    }  
                      
                    Object value = rs.getObject(columnName);  
                    name = underlineToCamel(name.toLowerCase());  
                    try {  
                        Field f = bean.getClass().getDeclaredField(name);  
                        if (f != null) {  
                            f.setAccessible(true);  
                            f.set(bean, value);  
                        }  
                    } catch (NoSuchFieldException e) {  
                        logger.error("表中字段：{"+name+"}在类：{"+clazz+"}没有对应的属性");  
                    } catch (IllegalArgumentException e) {  
                        logger.error("表中字段：{"+name+"}在类：{"+clazz+"}对应属性类型不一到");  
                    }  
                }  
                list.add(bean);  
            }  
        } catch (Exception e) {  
        	e.printStackTrace();
            throw e;  
        }  
          
        logger.info("hiveHandler successed the total size is:{"+list.size()+"}");  
          
        return list;  
    }  
    
    /** 
     * 下划线字段转成陀峰字段 
     * @author linbingwen 
     * @since  2016年10月20日  
     * @param param 
     * @return 
     */  
    private String underlineToCamel(String param) {  
        if (param == null || param.isEmpty()) {  
            return null;  
        }  
        int len = param.length();  
        StringBuilder sb = new StringBuilder(len);  
        for (int i = 0; i < len; i++) {  
            char c = param.charAt(i);  
            if (c == UNDERLINE) {  
                if (++i < len) {  
                    sb.append(Character.toUpperCase(param.charAt(i)));  
                }  
            } else {  
                sb.append(c);  
            }  
        }  
        return sb.toString();  
    }  
  

	public static void main(String[] args) {
	}
	
	
}

